using System;
using System.Threading;

namespace Common.Utilities.Dispatcher
{
    /// <summary>
    /// worker
    /// </summary>
    public interface IWorker
    {
        /// <summary>
        /// handler to worker thread
        /// </summary>
        Thread WorkerThread { get;}
        /// <summary>
        /// allow instruction to be changed at runtime
        /// </summary>
        InstructionBase Instruction{ get;}
        /// <summary>
        /// output
        /// </summary>
        ResultBase Output { get;}
        /// <summary>
        /// allow worker to be created based on component type
        /// </summary>
        Type ComponentType { get;}
        /// <summary>
        /// runtime context retrieved from appl domain
        /// </summary>
        RunContext Context { get; set;}

        /// <summary>
        /// this must be called before actual work
        /// </summary>
        /// <param name="ticketGuid"></param>
        /// <param name="request"></param>
        /// <param name="workflowName"></param>
        /// <param name="componentName"></param>
        void SetInstruction(Guid ticketGuid, InstructionBase request, string workflowName, string componentName);
        /// <summary>
        /// this is called within subflow, where runtime context is also initialized
        /// </summary>
        /// <param name="context"></param>
        /// <param name="ticketGuid"></param>
        /// <param name="request"></param>
        /// <param name="workflowName"></param>
        /// <param name="componentName"></param>
        void SetInstruction(RunContext context, Guid ticketGuid, InstructionBase request, string workflowName, string componentName);
        /// <summary>
        /// this is called synchronously, used in testing mode
        /// </summary>
        void DoWork();
        /// <summary>
        /// this is called by job dispatcher
        /// </summary>
        void DoWorkAsync();
        /// <summary>
        /// this is called by job monitor/manager
        /// </summary>
        void CancelWork();

        /// <summary></summary>
        event WorkerStarted WorkerStartedEvent;

        /// <summary></summary>
        event WorkerFinished WorkerFinishedEvent;

        /// <summary></summary>
        event WorkerHasError WorkerErredEvent;

        /// <summary></summary>
        event WorkerCancelled WorkerCancelledEvent;

        /// <summary></summary>
        event WorkerStatusChanged WorkerStatusChangedEvent;
    }
}
